package com.lagou.edu.filter;

import com.lagou.edu.bean.LimitBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @ClassName IpFilter
 * @Description TODO
 * @Auth ying.xiao
 * @Date 2021/4/21
 * @Version 1.0.0
 */
@Component
@RefreshScope
public class IpFilter implements GlobalFilter, Ordered {

    private static final Map<String, LimitBean> map = new HashMap();

    @Value("${ip.max}")
    private int MAX_VALUE;

    @Value("${ip.limitTime}")
    private int LIMIT_TIME;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 从上下⽂中取出request和response对象
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        //只针对注册接口进行过滤
        String url = request.getPath().value();
        if(!url.startsWith("/api/user/register")){
            return chain.filter(exchange);
        }

        // 从request对象中获取客户端ip
        String clientIp = getIpAddr(request);//127.0.0.1 0.0.0.0.0.1

        LimitBean limitBean = map.get(clientIp);
        if(null == limitBean){
            final AtomicInteger atomicInteger1 = new AtomicInteger(1);
            map.put(clientIp,new LimitBean(new Date(),atomicInteger1));
        }else{
            //超时删除
            if(new Date().getTime()-limitBean.getCreateTime().getTime()>LIMIT_TIME * 60 * 1000){
                map.remove(clientIp);
            }else{
                AtomicInteger atomicInteger = limitBean.getAtomicInteger();
                if(atomicInteger.get()>=MAX_VALUE){
                    String data = "您频繁进⾏注册，请求已被拒绝";
                    DataBuffer wrap =
                            response.bufferFactory().wrap(data.getBytes());
                    response.setStatusCode(HttpStatus.OK);
                    //设置编码
                    response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
                    return response.writeWith(Mono.just(wrap));
                }
                atomicInteger.incrementAndGet();
            }

        }

        return chain.filter(exchange);
    }
    public static String getIpAddr(ServerHttpRequest request) {
        String ip = request.getHeaders().getFirst("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeaders().getFirst("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeaders().getFirst("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = Objects.requireNonNull(request.getRemoteAddress()).getAddress().getHostAddress();
        }
        return ip;
    }
    @Override
    public int getOrder() {
        return 0;
    }
}
